import { IHasCenterObj, ModuleKeyType } from '../types'
import { getCenterPoint, setCssVariable } from '../utils'

/**
 * 项目配置中的宽高等信息
 */
export type SizeConfigType = {
    [key in ModuleKeyType]: IHasCenterObj
}

/**
 * 各个基础模块宽高和xy坐标配置
 */
export const sizeConfig: SizeConfigType = {
    /**
     * 容器相关配置
     */
    container: {
        width: 800,
        height: 800,
        x: 0,
        y: 0,
    },
    /**
     * 控制信号产生器相关配置
     */
    conSignal: {
        width: 150,
        height: 38,
        x: 310,
        y: 37,
    },
    /**
     * sm模块
     */
    sm: {
        width: 50,
        height: 38,
        x: 230,
        y: 108,
    },
    /**
     * 指令译码器
     */
    decoder: {
        width: 130,
        height: 38,
        x: 320,
        y: 106,
    },
    /**
     * 指令寄存器
     */
    ir: {
        width: 130,
        height: 38,
        x: 320,
        y: 176,
    },
    /**
     * RAM
     */
    ram: {
        width: 110,
        height: 97,
        x: 164,
        y: 286,
    },
    /**
     * 算数单元AU
     */
    au: {
        width: 110,
        height: 97,
        x: 422,
        y: 286,
    },
    /**
     * PSW
     */
    psw: {
        width: 54,
        height: 38,
        x: 332,
        y: 318,
    },
    /**
     * 3-1多路选择器
     */
    multiplexer31: {
        width: 110,
        height: 38,
        x: 164,
        y: 413,
    },
    /**
     * 程序计数器PC
     */
    pc: {
        width: 128,
        height: 56,
        x: 119,
        y: 580,
    },
    /**
     * 通用寄存器
     */
    reg: {
        width: 110,
        height: 97,
        x: 422,
        y: 520,
    },
    /**
     * 2-1多路选择器
     */
    multiplexer21: {
        width: 110,
        height: 38,
        x: 422,
        y: 650,
    },
    /**
     * BUS，只有width有效
     */
    bus: {
        width: 8,
        height: 0,
        x: 0,
        y: 0,
    },
    /**
     * 输出
     */
    input: {
        width: 60,
        height: 20,
        x: 740,
        y: 370,
    },
    /**
     * 输入
     */
    output: {
        width: 60,
        height: 20,
        x: 740,
        y: 470,
    },
}

/**
 * 将项目配置中的宽高等信息转换成css变量
 * @param config 项目配置
 */
function config2cssVar(config: SizeConfigType) {
    // 将所有配置转换成css变量，挂在到documentElement上
    for (const key in config) {
        const element = config[key as keyof SizeConfigType]
        for (const key2 in element) {
            if (['width', 'height', 'x', 'y'].includes(key2)) {
                const element2 =
                    element[key2 as keyof SizeConfigType[keyof SizeConfigType]]
                // 把小驼峰转换成短横线连接，若有数字则在每一个数字前加上短横线
                const prop = key.replace(/([A-Z0-9])/g, '-$1').toLowerCase()
                setCssVariable(`--${prop}-${key2}`, `${element2}px`)
            }
        }
    }
}

export function initSizeConfig() {
    config2cssVar(sizeConfig)

    document.getElementById('app')?.classList.remove('hide')

    // 一开始就计算好每一个模块的中心点
    for (const key in sizeConfig) {
        const element = sizeConfig[key as ModuleKeyType]
        element.center = {
            default: getCenterPoint(element),
            top: getCenterPoint(element, 'top'),
            bottom: getCenterPoint(element, 'bottom'),
            left: getCenterPoint(element, 'left'),
            right: getCenterPoint(element, 'right'),
        }
    }
}
